﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LuckyLoot.ServiceFacade.Contracts;
using LuckyLoot.Domain.Entities;
using LuckyLoot.Common.Validation;
using LuckyLoot.Common.Repositories;
using LuckyLoot.Common.Contexts;

namespace LuckyLoot.ServiceFacade.Implementation
{
    public class SupplyManagementService : ISupplyManagementService
    {
        #region ISupplyManagementService Members

        public Supply CreateSupply(string name, string description, DateTime acquisition, DateTime? expiration, int amount, int contentAmount, int supplyType, int measureType)
        {
            ValidState.Requires<ArgumentNullException>(!string.IsNullOrWhiteSpace(name));
            ValidState.Requires<ArgumentException>((acquisition != default(DateTime) && !(acquisition.Date > DateTime.Today)));
            ValidState.Requires<ArgumentNullException>(amount > 0);
            ValidState.Requires<ArgumentNullException>(contentAmount > 0);
            ValidState.Requires<ArgumentException>(Enum.ToObject(typeof(SupplyType), supplyType) != null);
            ValidState.Requires<ArgumentException>(Enum.ToObject(typeof(MeasureType), measureType) != null);


            Supply supply = new Supply();
            supply.Name = name;
            supply.Description = description;
            supply.Acquisition = acquisition;
            supply.Expiration = expiration;
            supply.Amount = amount;
            supply.ContentAmount = contentAmount;
            supply.Type = (SupplyType)supplyType;
            supply.MeasureType = (MeasureType)measureType;

            using (Repository<Supply, ApplicationContext> repository = new Repository<Supply, ApplicationContext>())
            {
                repository.Add(supply);
                repository.Save();
            }

            return supply;
        }

        public Supply UpdateSupply(int supplyID, string name, string description, DateTime acquisition, DateTime? expiration, int amount, int contentAmount, int supplyType, int measureType)
        {
            ValidState.Requires<ArgumentNullException>(supplyID < 0);
            ValidState.Requires<ArgumentNullException>(!string.IsNullOrWhiteSpace(name));
            ValidState.Requires<ArgumentException>((acquisition != default(DateTime) && acquisition.Date > DateTime.Today));
            ValidState.Requires<ArgumentNullException>(amount < 0);
            ValidState.Requires<ArgumentNullException>(contentAmount < 0);
            ValidState.Requires<ArgumentException>(Enum.ToObject(typeof(SupplyType), supplyType) != null);
            ValidState.Requires<ArgumentException>(Enum.ToObject(typeof(MeasureType), measureType) != null);


            Supply supply;
            using (Repository<Supply, ApplicationContext> repository = new Repository<Supply, ApplicationContext>())
            {
                supply = this.GetSupply(supplyID);

                supply.Name = name;
                supply.Description = description;
                supply.Acquisition = acquisition;
                supply.Expiration = expiration;
                supply.Amount = amount;
                supply.ContentAmount = contentAmount;
                supply.Type = (SupplyType)supplyType;
                supply.MeasureType = (MeasureType)measureType;

                repository.Edit(supply);
                repository.Save();
            }

            return supply;
        }

        public Supply GetSupply(int supplyID)
        {
            ValidState.Requires<ArgumentNullException>(supplyID > 0);

            Supply supply = null;
            using (Repository<Supply, ApplicationContext> repository = new Repository<Supply, ApplicationContext>())
            {
                supply = repository.GetById(supplyID);
                ValidState.Requires<InvalidOperationException>(supply != null, string.Format("Não foi possível encontrar o material de id {0}.", supplyID));

            }

            return supply;
        }

        #endregion

        #region ISupplyManagementService Members


        public List<Supply> GetAllSupplies()
        {
            List<Supply> supplies = null;
            using (Repository<Supply, ApplicationContext> repository = new Repository<Supply, ApplicationContext>())
            {
                supplies = repository.GetAll().ToList<Supply>();
            }

            return supplies;
        }

        #endregion
    }
}
